﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web.Caching;
using System.Web;

namespace Twi.COMMON.Core
{
    /*
    * Copyright: ©2010-2014 Tysingsoft、Twilight软件开发工作室版权所有
    * Author: xuzhihong
    * Edit date: 2014-07-02
    * Description: 日志相关
    * 
    */
    public class TwiLogHelper
    {
        public static string LogfileDirectory =TwiPathHelper.MapPath(string.Format("/Log/{0}/{1}/{2}/",DateTime.Today.ToString("yyyy"),DateTime.Today.ToString("MM"),DateTime.Today.ToString("dd")));
        public static string filePrefix = "Log";
        /// <summary>
        /// 写日志文件
        /// </summary>
        /// <param name="log"></param>
        /// <param name="fileName"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void WriteLog(TwiLog log, TwiLogGrade logGrade, string msg = "", string giveIp = "")
        {
            bool needWriteLog = IsNeedWriteLog(logGrade);
            if (needWriteLog)
            {
                //string ip = TwiNetHelper.GetIp();
                string ip = giveIp;
                if (string.IsNullOrEmpty(giveIp))
                {
                    ip = TwiNetHelper.GetIp();
                }
                string fileName = string.Format("{0}{1}_{2}{3}", filePrefix, DateTime.Now.ToString("yyyyMMdd"), ip, ".txt");
                fileName = string.IsNullOrEmpty(log.LogFileName) ? fileName : log.LogFileName;
                TwiFileHelper.CreateDirectory(LogfileDirectory);
                fileName = LogfileDirectory + fileName;
                using (StreamWriter sw = new StreamWriter(fileName, true))
                {
                    sw.WriteLine(string.Format("\r\n【{0}】 {1} {2}", logGrade.ToString(), TwiDateHelper.GetNowDateTime(), ip));
                    if (!string.IsNullOrEmpty(msg))
                    {
                        sw.WriteLine(string.Format("\t{0}", msg));
                    }
                    if (log != null)
                    {
                        sw.WriteLine("\t-----TwiLog对象------");
                        sw.WriteLine("\t日志编号：" + log.LogID);
                        sw.WriteLine("\t功能模块名：" + log.ModuleName);
                        sw.WriteLine("\t类名：" + log.ClassName);
                        sw.WriteLine("\t方法名：" + log.ModuleName);
                        sw.WriteLine("\t参数：" + log.ParametersToString);
                        sw.WriteLine("\t方法注释：" + log.MethodRemark);
                        sw.WriteLine("\t描述：" + log.Description);
                        sw.WriteLine("\t-----------------------");
                    }
                }
            }           
        }

        public static void WriteTwiReturnLog(TwiReturn twi, TwiLogGrade logGrade, string msg = "", string giveIp = "")
        {
            bool needWriteLog = IsNeedWriteLog(logGrade);
            if (needWriteLog)
            {
                //string ip = TwiNetHelper.GetIp();
                string ip = giveIp;
                if (string.IsNullOrEmpty(giveIp))
                {
                    ip = TwiNetHelper.GetIp();
                }
                string fileName = string.Format("{0}{1}_{2}{3}", filePrefix, DateTime.Now.ToString("yyyyMMdd"), ip, ".txt");
                TwiFileHelper.CreateDirectory(LogfileDirectory);
                fileName = LogfileDirectory + fileName;
                using (StreamWriter sw = new StreamWriter(fileName, true))
                {
                    sw.WriteLine(string.Format("\r\n【{0}】 {1} {2}", logGrade.ToString(), TwiDateHelper.GetNowDateTime(), ip));
                    if (!string.IsNullOrEmpty(msg))
                    {
                        sw.WriteLine(string.Format("\t{0}", msg));
                    }
                    if (twi != null) 
                    {
                        sw.WriteLine("\t-----TwiReturn对象------");
                        sw.WriteLine("\tSuccess：" + twi.success);
                        sw.WriteLine("\tErrors:" + twi.errors);
                        sw.WriteLine("\tHasRight:" + twi.hasRight);
                        sw.WriteLine("\tMessage：" + twi.message);
                        sw.WriteLine("\tTotalCount：" + twi.totalCount);
                        sw.WriteLine("\tData：" + JSSerialize.Serialize(twi.data));
                        sw.WriteLine("\tRightName：" + twi.rightName);
                        sw.WriteLine("\t-----------------------");
                    }
                }
            }
        }

        /// <summary>
        /// 写提示信息
        /// </summary>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        /// <param name="msg"></param>
        public static void Info(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.Info,giveIp);
        }

        /// <summary>
        /// 写成功信息
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void Success(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.Success, giveIp);
        }

        /// <summary>
        /// 写错误日志
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void Error(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.Error, giveIp);
        }

        /// <summary>
        /// 写已知错误日志
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void KnowError(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.KnowError, giveIp);
        }

        /// <summary>
        /// 写Debugger信息日志
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void Debugger(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.Debugger, giveIp);
        }

        /// <summary>
        /// 写开始标志信息日志
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void Begin(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.Begin, giveIp);
        }

        /// <summary>
        /// 写结束标志信息日志
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void End(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.End, giveIp);
        }

        /// <summary>
        /// 写无标志信息日志
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="giveIp">请求IP（不填会自动获取）</param>
        public static void None(string msg, string giveIp = "")
        {
            TwiLogHelper.Write(msg, TwiLogGrade.None, giveIp);
        }  

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="msg">日志信息</param>
        /// <param name="logGrade">日志类别</param>
        public static void Write(string msg,TwiLogGrade logGrade,string giveIp="")
        {
            try
            {
                bool needWriteLog = IsNeedWriteLog(logGrade);
                if (needWriteLog)
                {
                    string ip = giveIp;
                    if (string.IsNullOrEmpty(giveIp))
                    {
                        ip = TwiNetHelper.GetIp();
                    }
                    string fileName = string.Format("{0}{1}_{2}{3}", filePrefix, DateTime.Now.ToString("yyyyMMdd"), ip, ".txt");
                    TwiFileHelper.CreateDirectory(LogfileDirectory);
                    fileName = LogfileDirectory + fileName;
                    using (StreamWriter sw = new StreamWriter(fileName, true))
                    {
                        if (logGrade != TwiLogGrade.None)
                        {
                            sw.WriteLine(string.Format("\r\n【{0}】 {1} {2}", logGrade.ToString(), TwiDateHelper.GetNowDateTime(), ip));
                        }
                        sw.WriteLine(string.Format("\t{0}", msg));
                    }
                }
            }
            catch
            {
                //如果写日志异常，则直接过
            }
        }

        /// <summary>
        /// 写简单格式日志（简单日志：值输入什么写什么，不做特殊处理）
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="fileName">文件名,不含后缀,null为默认</param>
        /// <param name="directory">目录，null为默认</param>
        public static void WriteSimple(string msg, TwiLogGrade logGrade, string fileName = null, string directory = null, string giveIp = "")
        {
            try
            {
                bool needWriteLog = IsNeedWriteLog(logGrade);
                if (needWriteLog)
                {
                    if (fileName == null)
                    {
                        string ip = giveIp;
                        if (string.IsNullOrEmpty(giveIp))
                        {
                            ip = TwiNetHelper.GetIp();
                        }
                        fileName = string.Format("{0}{1}_{2}{3}", filePrefix, DateTime.Now.ToString("yyyyMMdd"), ip, ".txt");
                    }
                    else {
                        fileName += ".txt"; 
                    }
                    directory = directory ?? LogfileDirectory;
                    TwiFileHelper.CreateDirectory(directory);
                    fileName = directory + fileName;
                    using (StreamWriter sw = new StreamWriter(fileName, true))
                    {
                        sw.WriteLine(string.Format("{0}", msg));
                    }
                }
            }
            catch
            {
                //如果写日志异常，则直接过
            }
        }

        /// <summary>
        /// 是否需要写日志
        /// </summary>
        /// <returns></returns>
        public static bool IsNeedWriteLog(TwiLogGrade logGrade) {
            bool needWrite = true;
            TwiLogModel logModel = GetTwiLogMode();
            if (logModel == TwiLogModel.Release)  //真实环境使用，最常见所以放第一个位置
            {
                if (logGrade != TwiLogGrade.Error && logGrade != TwiLogGrade.KnowError)
                {
                    needWrite = false;
                }
            }
            else if (logModel == TwiLogModel.Debugger)
            {
                //全部记录
                needWrite = true;
            }
            else if (logModel == TwiLogModel.None)
            {
                //全部不记录
                needWrite = false;
            }
            else
            {
                //其他则也都认为是发布模式：只记录错误
                if (logGrade != TwiLogGrade.Error && logGrade != TwiLogGrade.KnowError)
                {
                    needWrite = false;
                }
            }
            return needWrite;
        }

        /// <summary>
        /// 获取日志记录模式
        /// </summary>
        /// <returns></returns>
        public static TwiLogModel GetTwiLogMode()
        {
            if (HttpContext.Current == null) {
                try
                {
                    string configModel = TwiConfigHelper.GetAppSettingValue("TwiLogMode");
                    configModel = string.IsNullOrEmpty(configModel) ? "1" : configModel;
                    return TwiEnumHelper.GetEnumByNameOrValue<TwiLogModel>(configModel);
                }
                catch {
                    return TwiLogModel.Release;
                }                
            }
            if (HttpContext.Current.Session == null)
            {
                string configModel = TwiConfigHelper.GetAppSettingValue("TwiLogMode");
                configModel = string.IsNullOrEmpty(configModel) ? "1" : configModel;
                return TwiEnumHelper.GetEnumByNameOrValue < TwiLogModel >(configModel);
            }
            else
            {
                if (HttpContext.Current.Session["TwiLogMode"] == null)
                {
                    string configModel = TwiConfigHelper.GetAppSettingValue("TwiLogMode");
                    configModel = string.IsNullOrEmpty(configModel) ? "1" : configModel;
                    HttpContext.Current.Session["TwiLogMode"] = configModel;
                }
                return TwiEnumHelper.GetEnumByNameOrValue<TwiLogModel>("" + HttpContext.Current.Session["TwiLogMode"]);
            }
        }
    }

    public class TwiLog
    {
        /// <summary>
        /// 日志编号（自动生成：只读）
        /// </summary>
        public string LogID
        {
            get
            {
                return DateTime.Now.ToString("yyyyMMddHHmmssfffff");
            }
        }
        /// <summary>
        /// 日志目录（只读）
        /// </summary>
        public string LogDirectory
        {
            get
            {
                return TwiPathHelper.MapPath(string.Format("/Log/{0}/{1}/{2}", DateTime.Today.ToString("yyyy"), DateTime.Today.ToString("MM"),DateTime.Today.ToString("dd")));
            }
        }
        /// <summary>
        /// 日志文件名（不带路径，不填则自动按日期生成）
        /// </summary>
        public string LogFileName
        {
            get;
            set;
        }
        /// <summary>
        /// 功能模块名
        /// </summary>
        public string ModuleName
        {
            get;
            set;
        }
        /// <summary>
        /// 类名
        /// </summary>
        public string ClassName
        {
            get;
            set;
        }
        /// <summary>
        /// 方法名
        /// </summary>
        public string MethodName
        {
            get;
            set;
        }
        /// <summary>
        /// 方法注释
        /// </summary>
        public string MethodRemark
        {
            get;
            set;
        }
        /// <summary>
        /// 参数（多个参数请自定义隔开）
        /// </summary>
        /// <example>
        /// FName:"xuzhihong";FCode="123456";
        /// </example>
        public string ParametersToString
        {
            get;
            set;
        }
        /// <summary>
        /// 描述
        /// </summary>
        public string Description
        {
            get;
            set;
        }
    }


    /// <summary>
    /// 日志类别
    /// </summary>
    public enum TwiLogGrade
    {
        Info = 0,
        Success = 1,
        Error = 2,
        KnowError = 3,
        Debugger = 4,        
        Begin = 5,
        End = 6,
        None = 7
    }

    /// <summary>
    /// 日志记录模式
    /// -----------------------------------------------
    /// 模式说明：（在Webconfig文件的TwiLogMode中设定）如：<add key="TwiLogMode" value="1"/>
    /// Debugger模式：所有的都会记录
    /// Release模式：只会记录Error和KnowError
    /// None模式：不会记录日志
    /// -----------------------------------------------
    /// </summary>
    public enum TwiLogModel 
    { 
        None = 0,        
        Release = 1,
        Debugger = 2
    }
}
